package net.onceface.core.domain;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.NoResultException;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import net.onceface.core.domain.mappedsuper.Party;
import net.onceface.infra.domain.NamedParameters;

import org.hibernate.annotations.Where;

/**
 * 商品实体类
 */
@Entity
@Table(name = "SYS_PRODUCT")
@NamedQueries({
	@NamedQuery(name = "Produc.findProductFeatureById", query = "SELECT _product FROM Product _product WHERE _product.id = :id")
})
public class Product extends Party{

	private static final long serialVersionUID = 7665000623820269591L;
	
	/**
	 * 商品条码
	 * **/
	@Column(name = "SN")
	private String sn;
	
	/**
	 * 商品价格
	 * **/
	@Column(name = "PRICE")
	private double price;
	
	/**
	 * 分类ID
	 * **/
	@Column(name = "CATEGORY_ID")
	private Long catgoryId;
	
	/**
	 * 商品原价
	 * **/
	@Column(name = "ORIGINAL_PRICE")
	private double originalPrice;
	
	/**
	 * 商品规格ID
	 * **/
	@Column(name = "SPEC_ID")
	private Integer specId;
	
	/**
	 * 商品规格名
	 * **/
	@Column(name = "SPEC_NAME")
	private String specName;
	
	/**
	 * 上否上架
	 * **/
	@Column(name="SALE")
	private boolean sale;
	
	/**
	 * 库存
	 * **/
	@Column(name = "STOCK")
	private int stock;
	
	/**
	 * 商品图片
	 * **/
	@Column(name = "PICTURE")
	private String picture;
	
	/**
	 * 关注度
	 * **/
	@Column(name = "COLLECTION")
	private Integer collection;
	
	/**
	 * 总销量
	 * **/
	@Column(name = "TOTAL_SALE_VOLUME")
	private Integer totalSaleVolume;
	
	/**
	 * 月销量
	 * **/
	@Column(name = "MOON_SALE_VOLUME")
	private Integer moonSaleVolume;
	
	/**
	 * 商品图片列表
	 * **/
	@OneToMany(fetch = FetchType.LAZY)
	@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")
	private List<ProductPicture> productPicture;
	
	/**
	 * 所属分类
	 * **/
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "category_ID", insertable=false, updatable=false)
	private Category category;
	
	/**
	 * 商品规格
	 * **/
	@OneToMany(fetch = FetchType.LAZY)
	@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")
	@Where(clause="DISABLED=1 AND SALE=1 AND ABOLISH_DATE>NOW()")
	private List<Spec> spec;
	
	/****
	 * 所属专题
	 */
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name = "SYS_PRODUCT_RELATION",
			joinColumns = @JoinColumn(name = "PRODUCT_ID"),
			inverseJoinColumns = @JoinColumn(name = "FEATURE_ID"))
	@Where(clause = "DISABLED=1 AND START_TIME > NOW() AND ABOLISH_DATE < NOW()")
	private Set<Feature> features;
	
	/**
	 * 根据商品ID查询商品，包含专题信息
	 * **/
	public static Product getProductFeatureById(Long id){
		return getRepository().createNamedQuery("Produc.findProductFeatureById")
		.addParameter("id", id)
		.singleResult();
	}
		
	/**
	 * 根据商品ID查询有效商品
	 * **/
	public static Product getValidProductById(Long id){
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("id", id);
		param.put("sale", true);
		List<Product> products = getRepository()
				.findByProperties(Product.class, NamedParameters.create(param));
		if(products.size() > 0){
			return products.get(0);
		}
		return null;
	}
	
	/**
	 * 根据商品ID 图片ID修改默认图
	 * **/
	public static boolean setPicture(Long id, String picture, Long picId){
		ProductPicture.resetAllDefaultPicture(id, picId);
		return resetPictureByProductId(id, picture);
	}
	
	/**
	 * 根据商品ID删除默认图片(商品id，图片地址)
	 * 修改成功返回真
	 * **/
	public static boolean resetPictureByProductId(Long id, String picture) {
		try {
			Product product = Product.get(Product.class, id);
			product.picture = picture;
			product.save();
			return true;
		}catch(NoResultException e){
			return false;
		}
	}
	
	public String getSn() {
		return sn;
	}


	public void setSn(String sn) {
		this.sn = sn;
	}


	public double getPrice() {
		return price;
	}
	public Category getCategory() {
		return category;
	}

	public List<Spec> getSpec() {
		return spec;
	}

	public void setSpec(List<Spec> spec) {
		this.spec = spec;
	}

	public List<ProductPicture> getProductPicture() {
		return productPicture;
	}

	public void setProductPicture(List<ProductPicture> productPicture) {
		this.productPicture = productPicture;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public void setStock(int stock) {
		this.stock = stock;
	}

	public Long getCatgoryId() {
		return catgoryId;
	}

	public void setCatgoryId(Long catgoryId) {
		this.catgoryId = catgoryId;
	}


	public void setPrice(double price) {
		this.price = price;
	}


	public double getOriginalPrice() {
		return originalPrice;
	}


	public boolean isSale() {
		return sale;
	}


	public void setSale(boolean sale) {
		this.sale = sale;
	}


	public void setOriginalPrice(double originalPrice) {
		this.originalPrice = originalPrice;
	}


	public Integer getSpecId() {
		return specId;
	}


	public void setSpecId(Integer specId) {
		this.specId = specId;
	}


	public String getSpecName() {
		return specName;
	}


	public void setSpecName(String specName) {
		this.specName = specName;
	}


	public Integer getStock() {
		return stock;
	}


	public void setStock(Integer stock) {
		this.stock = stock;
	}


	public String getPicture() {
		return picture;
	}


	public void setPicture(String picture) {
		this.picture = picture;
	}


	public Integer getCollection() {
		return collection;
	}


	public void setCollection(Integer collection) {
		this.collection = collection;
	}


	public Integer getTotalSaleVolume() {
		return totalSaleVolume;
	}


	public void setTotalSaleVolume(Integer totalSaleVolume) {
		this.totalSaleVolume = totalSaleVolume;
	}


	public Integer getMoonSaleVolume() {
		return moonSaleVolume;
	}


	public void setMoonSaleVolume(Integer moonSaleVolume) {
		this.moonSaleVolume = moonSaleVolume;
	}
	
	public Set<Feature> getFeatures() {
		return features;
	}

	public void setFeatures(Set<Feature> features) {
		this.features = features;
	}

	@Override
	public String[] businessKeys() {
		// TODO Auto-generated method stub
		return null;
	}

}
